﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Urs.Core;
using Urs.Core.Caching;
using Urs.Data.Domain.Stores;
using Urs.Data.Domain.Common;
using Urs.Data.Domain.Users;
using Urs.Data.Domain.Media;
using Urs.Data.Domain.Configuration;
using Plugin.Api.Models.Catalog;
using Plugin.Api.Models.Favorites;
using Plugin.Api.Models.Media;
using Plugin.Api.Models.Goods;
using Urs.Services.Stores;
using Urs.Services.Common;
using Urs.Services.Users;
using Urs.Services.Localization;
using Urs.Services.Media;
using Urs.Services.Security;
using Urs.Framework;
using Urs.Framework.Controllers;

namespace Plugin.Api.Controllers
{
    /// <summary>
    /// 收藏夹
    /// </summary>
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/favorites")]
    [ApiController]
    public class FavoritesController : BaseApiController
    {
        private readonly ILocalizationService _localizationService;
        private readonly IUserService _userService;
        private readonly IWorkContext _workContext;
        private readonly MediaSettings _mediaSettings;
        private readonly IGoodsService _goodsService;
        private readonly IPermissionService _permissionService;
        private readonly ICacheManager _cacheManager;
        private readonly IPictureService _pictureService;
        private readonly IWebHelper _webHelper;
        private readonly IFavoritesService _favoritesService;
        private readonly IGoodsParameterService _goodsParameterService;

        /// <summary>
        /// 构造器
        /// </summary>
        public FavoritesController(ILocalizationService localizationService,
            IUserService userService,
            IWorkContext workContext,
            MediaSettings mediaSettings,
            IGoodsService goodsService,
            IPermissionService permissionService,
            ICacheManager cacheManager,
            IPictureService pictureService,
            IWebHelper webHelper,
            IFavoritesService favoritesService,
            IGoodsParameterService goodsParameterService)
        {
            this._localizationService = localizationService;
            this._userService = userService;
            this._workContext = workContext;
            this._mediaSettings = mediaSettings;
            this._goodsService = goodsService;
            this._permissionService = permissionService;
            this._cacheManager = cacheManager;
            this._pictureService = pictureService;
            this._webHelper = webHelper;
            this._favoritesService = favoritesService;
            this._goodsParameterService = goodsParameterService;
        }

        #region Utilities

        [NonAction]
        protected IList<MoSpecification> PrepareGoodsSpecificationModel(Goods goods)
        {
            if (goods == null)
                throw new ArgumentNullException("goods");

                var model = _goodsParameterService.GetGoodsParameterMappingByGoodsId(goods.Id, null, true)
                   .Select(psa =>
                   {
                       return new MoSpecification()
                       {
                           Name = psa.GoodsParameterOption.Mapping.Name,
                           Value = !String.IsNullOrEmpty(psa.CustomValue) ? psa.CustomValue : psa.GoodsParameterOption.Name,
                       };
                   }).ToList();
                return model;
        }


        [NonAction]
        protected IEnumerable<MoGoodsOverview> PrepareGoodsOverviewModels(IEnumerable<Goods> list,
            bool preparePriceModel = true, bool preparePictureModel = true,
            int? goodsThumbPictureSize = null, bool prepareGoodsParameters = false, bool prepareGoodsTag = false,
            bool forceRedirectionAfterAddingToCart = false, bool prepareFullDescription = false)
        {
            if (list == null)
                throw new ArgumentNullException("list");

            var models = new List<MoGoodsOverview>();
            foreach (var goods in list)
            {
                var model = new MoGoodsOverview()
                {
                    Id = goods.Id,
                    Sku = goods.Sku,
                    Name = goods.Name,
                    Short = goods.ShortDescription,
                    Qty = goods.StockQuantity,
                    SaleVolume = goods.SaleVolume
                };
                if (prepareFullDescription)
                {
                    model.Full = goods.FullDescription;
                }
                //price
                if (preparePriceModel)
                {
                    #region Prepare goods price

                    var priceModel = new MoGoodsOverview.MoPrice();
                    priceModel.OldPrice = PriceFormatter.FormatPrice(goods.OldPrice);
                    priceModel.Price = PriceFormatter.FormatPrice(goods.Price);
                    model.Price = priceModel;
                    #endregion
                }

                //picture
                if (preparePictureModel)
                {
                    #region Prepare goods picture

                    //If a size has been set in the view, we use it in priority
                    int pictureSize = goodsThumbPictureSize.HasValue ? goodsThumbPictureSize.Value : _mediaSettings.GoodsThumbPictureSize;
                   
                        var picture = goods.GetDefaultGoodsPicture(_pictureService);
                        var pictureModel = new MoPicture()
                        {
                            NormalUrl = _pictureService.GetPictureUrl(picture, pictureSize),
                            BigUrl = _pictureService.GetPictureUrl(picture)
                        };
                        model.Picture = pictureModel;
                   
                    #endregion
                }

                //specs
                if (prepareGoodsParameters)
                {
                    //specs for comparing
                    model.Specs = PrepareGoodsSpecificationModel(goods);
                }

                if (prepareGoodsTag)
                {
                    for (int i = 0; i < goods.GoodsTags.Count; i++)
                    {
                        var pt = goods.GoodsTags.ToList()[i];
                        model.Tags.Add(new MoGoodsOverview.MoGoodsTag()
                        {
                            Id = pt.GoodsTag.Id,
                            Name = pt.GoodsTag.Name
                        });
                    }
                }
                models.Add(model);
            }
            return models;
        }


        [NonAction]
        protected MoFavoritesList PrepareFavoritesModel(PagingFiltering command, int userId, int? picsize,
            bool specshow = false, bool tagshow = false, bool fullshow = false)
        {
            var model = new MoFavoritesList();

            if (command.PageSize <= 0) command.PageSize = command.PageSize > 0 ? command.PageSize : 5;
            if (command.PageNumber <= 0) command.PageNumber = 1;

            var favorites = _favoritesService.GetFavorites(userId, pageIndex: command.PageIndex, pageSize: command.PageSize);
            var list = _goodsService.GetGoodssByIds(favorites.Select(f => f.GoodsId).ToArray(), true);
            model.UserId = userId;
            model.Paging.Page = command.PageNumber;
            model.Paging.Size = command.PageSize;
            model.Items = PrepareGoodsOverviewModels(list, true, true, picsize,
                    prepareGoodsParameters: specshow, prepareGoodsTag: tagshow, prepareFullDescription: fullshow).ToList();
            model.Paging.TotalPage = favorites.TotalPages;


            return model;
        }
        #endregion

        /// <summary>
        /// 获取收藏夹列表
        /// </summary>
        /// <param name="cId">用户Id</param>
        /// <param name="picsize">图片尺寸</param>
        /// <param name="specshow">是否参数</param>
        /// <param name="tagshow">是否显示商品标签</param>
        /// <param name="fullshow">是否显示商品内容</param>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<ApiResponse<MoFavoritesList>> Get(int cId, int? picsize,
            bool specshow = false, bool tagshow = false, bool fullshow = false, int page = 1, int size = 12)
        {
            var user = RegisterUser;
            if (user == null || user.Deleted)
                return ApiResponse<MoFavoritesList>.NotFound();

            var data = await Task.Run(() =>
            {
                var command = new PagingFiltering
                {
                    PageNumber = page,
                    PageSize = size
                };
                return PrepareFavoritesModel(command,cId, picsize, specshow: specshow, tagshow: tagshow, fullshow: fullshow);
            });

            return ApiResponse<MoFavoritesList>.Success(data);
        }

        /// <summary>
        /// 提交收藏夹[Auth]
        /// </summary>
        /// <param name="model">商品收藏夹对象</param>
        /// <returns></returns>
        [Authorize]
        [HttpPost("submit")]
        public async Task<ApiResponse> Submit(MoFavoritesRequest model)
        {
            var user = RegisterUser;

            var goods = _goodsService.GetGoodsById(model.GoodsId);
            if (goods == null || goods.Deleted)
                return ApiResponse.Warn("商品不正确");

            var entity = new Favorites();
            entity.UserId = user.Id;
            entity.GoodsId = model.GoodsId;
            entity.CreateTime = DateTime.Now;
            _favoritesService.InsertFavorites(entity);

            return ApiResponse.Success();
        }

    }
}
